
package com.platform.modules.app.controller;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.platform.annotation.IgnoreAuth;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.*;
import com.platform.modules.mall.dao.MallShopsDao;
import com.platform.modules.mall.entity.*;
import com.platform.modules.mall.entity.dto.MallShopsDto;
import com.platform.modules.mall.location.utils.LocationUtil;
import com.platform.modules.mall.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.logstash.logback.encoder.org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 店铺
 *
 * @author
 */
@Slf4j
@RestController
@RequestMapping("/app/shops")
@Api(tags = "AppShopsController|店铺管理接口")
public class AppShopsController extends AppBaseController {
    @Autowired
    private MallShopsService shopsService;
    @Autowired
    private MallShopsCategoryService shopsCategoryService;
    @Autowired
    private MallShopsGoodsService shopsGoodsService;
    @Autowired
    MallCardShopsService cardShopsService;
    @Resource
    private JedisUtil jedisUtil;
    @Resource
    private MallCollectService collectService;
    @Resource
    private MallAssociTagService associTagService;
    @Resource
    private MallShopsToActivityService shopsToActivityService;
    @Resource
    private MallActivityService activityService;
    @Resource
    private MallShopsFeedbackService feedbackService;

    @PostMapping("addFeedback")
    public RestResponse addFeedback(@RequestBody @Valid MallShopsFeedbackEntity entity){
        MallShopsEntity shopsEntity = shopsService.getById(entity.getShopsId());
        if(shopsEntity == null){
            return RestResponse.error("店铺信息获取失败！");
        }
        entity.setName(shopsEntity.getName());
        entity.setAddTime(new Date());
        feedbackService.add(entity);
        return RestResponse.success();
    }

    /**
     * 商圈详情
     */
    @GetMapping("/tradeAreaInfo")
    @ApiOperation(value = "商圈详情", notes = "商圈详情")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "id", value = "店铺ID", example = "1", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "loca", value = "经纬度", example = "1", required = true, dataType = "string")
    })
    public RestResponse tradeAreaInfo(@RequestParam Map<String, Object> map) {
        String id = map.get("id").toString();
        if (StringUtils.isEmpty(id)) {
            return RestResponse.error("参数错误！");
        }

        JSONObject result = null;
        // 店铺基础信息走redis缓存
        result = jedisUtil.getCache(Constant.SHOPS_DETAILS+id,
                ()->{
                    JSONObject resultCache = new JSONObject();
                    MallShopsEntity baseInfo = shopsService.getOne(new QueryWrapper<MallShopsEntity>()
                            .select("ID","NAME","DETAILS","WORK_TIME","ST_X(location) LATITUDE","ST_Y(location) LONGITUDE","IMG_URL","IMG_LIST","TELEPHONE")
                            .eq("ID",id)
                            .eq("TYPE",3)
                    );
                    if(baseInfo == null){
                        throw new BusinessException("未找到指定的商圈信息！");
                    }

                    // 查询商圈下各个分类店铺的信息


                    // 获取热门餐厅信息
                    map.put("tradeAreaId",id);
                    map.put("hot",1);
                    map.put("limit",6);
                    Page<Map<String,Object>> page = new Query<Map<String,Object>>(map).getPage();

                    // 获取附近的商圈
                    String distance = String.format("FLOOR(ST_Distance( ST_GeomFromText ( 'point(%s)',4326), location))  distance",baseInfo.getLatitude()+" "+baseInfo.getLongitude());
                    List<Map<String,Object>> nearbyTradeArea = shopsService.listMaps(new QueryWrapper<MallShopsEntity>()
                            .select("ID as id","NAME as name",distance,"IMG_URL as img")
                            .eq("TYPE",3)
                            .ne("ID",id)
                            .orderByAsc("distance")
                    );
                    nearbyTradeArea.forEach(x->{
                        x.put("categoryCount",((MallShopsDao)shopsService.getBaseMapper()).getCategoryCount(x.get("id").toString()));
                    });

                    // 获取商圈下各分类的数据
                    resultCache.put("categoryCount",((MallShopsDao)shopsService.getBaseMapper()).getCategoryCount(id));

                    resultCache.put("shops",((MallShopsDao)shopsService.getBaseMapper()).getNearbyShopListNew(page,map));
                    resultCache.put("baseInfo",baseInfo);
                    resultCache.put("nearbyTradeArea",nearbyTradeArea);
                    return resultCache;
                },
                JSONObject.class
        );
        return RestResponse.success().put("data", result);
    }

    /**
     * 获取距离最近的店铺详情
     */
    @GetMapping("/nearbyShopsDetails")
    @ApiOperation(value = "获取距离最近的店铺详情", notes = "店铺详情")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "id", value = "店铺ID", example = "1", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "loca", value = "经纬度", example = "1", required = true, dataType = "string")
    })
    public RestResponse nearbyShopsDetails(@RequestParam Map<String,Object> params) {
        ValidUtils.allNotNull(params.get("location"));
        String distance = String.format("FLOOR(ST_Distance( ST_GeomFromText ( 'point(%s)',4326), location))  distance",params.get("location").toString().replace(","," "));
        params.put("topLimit",1);
        params.put("sortName", "distance");
        if(StringUtils.isNotBlank(params.get("brandId").toString())){
            params.put("brandId",params.get("brandId"));
        }
        params.put("select",String.format("S.id,%s",distance));
        List<Map<String,Object>> results = ((MallShopsDao)shopsService.getBaseMapper()).getShopsInfo(null,params);
        String shopsId;
        if(results == null || results.isEmpty() || results.get(0).isEmpty() || StringUtils.isBlank(shopsId = results.get(0).get("id").toString())){
            throw new BusinessException("未查到符合条件的店铺！");
        }
        return this.shopsDetails(shopsId,params.get("location").toString());
    }

    /**
     * 店铺详情
     */
    @GetMapping("/shopsDetails")
    @ApiOperation(value = "店铺详情", notes = "店铺详情")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "id", value = "店铺ID", example = "1", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "loca", value = "经纬度", example = "1", required = true, dataType = "string")
    })
    public RestResponse shopsDetails(String id, String location) {
        if (StringUtils.isEmpty(id) || StringUtils.isEmpty(location)) {
            return RestResponse.error("参数错误！");
        }

        JSONObject result = null;
        // 店铺基础信息走redis缓存
        result = jedisUtil.getCache(Constant.SHOPS_DETAILS+id,
                ()->{
                    JSONObject resultCache = new JSONObject();
                    MallShopsDto shopsEntity = shopsService.getShopBaseInfo(id,location);
                    resultCache.put("baseInfo",shopsEntity);
                    resultCache.put("tradeAreaInfo",shopsService.tradeAreaInfo(shopsEntity.getTradeAreaId(),location));
                    return resultCache;
                    },
                JSONObject.class
        );

        // 店铺商品信息不走缓存
        Map<String,Object> parmas = new HashMap<>(8);
        parmas.put("shopId",id);
        Page page = shopsGoodsService.getShopCardList(parmas);
        result.put("shopGoods",page);
        // 是否收藏
        result.put("isCollect",collectService.isCollect(getUserId(),id));
        // 获取线下活动信息
        List<String> activityIds = shopsToActivityService.getActivityIdList(id);
        if(activityIds != null && !activityIds.isEmpty()){
            result.put("activityList",activityService.lambdaQuery().in(MallActivityEntity::getId,activityIds).list());
        }
        return RestResponse.success().put("data", result);
    }

    /**
     * 店铺列表
     */
    @IgnoreAuth
    @GetMapping("/nearbyShops")
    @ApiOperation(value = "周边店铺列表", notes = "周边店铺列表")
    @ApiImplicitParam(paramType = "query", name = "location", value = "经纬度", example = "1", required = true, dataType = "string")
    public RestResponse nearbyShops(@RequestParam Map<String, Object> map) {
        if (StringUtils.isEmpty((String) map.get("location"))) {
            return RestResponse.error("无法获取当前位置！");
        }
        Object range = map.get("range");
        if(ObjectUtil.isNotEmpty(map.get("userId"))){
            // 分页查询用户已经收藏的店铺ID
            List<String> list = collectService.lambdaQuery()
                    .select(MallCollectEntity::getGoodsId)
                    .eq(MallCollectEntity::getUserId, map.get("userId"))
                    .eq(MallCollectEntity::getType,1)
                    .orderByDesc(MallCollectEntity::getAddTime)
                    .list().stream().map(MallCollectEntity::getGoodsId).collect(Collectors.toList());
            map.put("shopsIds",list);
            map.put("notUseIsOnSale", 1);
        }
        try {
            String[] location = ((String) map.get("location")).split(",");
            // 注意 mysql8.0 以上 配合新的距离计算函数 此处需要换成 0，1  （纬度，经度）  旧版本使用 1，0 （经度，纬度）
            map.put("location", location[0] + " " + location[1]);
            if(range != null){
                map.put("scope", LocationUtil.getAroundLocations(Double.parseDouble(location[0]), Double.parseDouble(location[1]), 30,Float.parseFloat(range.toString())));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return RestResponse.error("获取当前位置出错！");
        }
        map.put("sidx", "distance");
        map.put("asc", true);
        Page<Map<String,Object>> page = new Query<Map<String,Object>>(map).getPage();
        page.setRecords(((MallShopsDao)shopsService.getBaseMapper()).getNearbyShopListNew(page,map));

        // 获取店铺标签
        for(Map<String,Object> item : page.getRecords()){
            String shopsId;
            item.put("tag",jedisUtil.getCache(
                    Constant.SHOPS_TAG+ (shopsId = (String) item.get("id")),
                    ()-> associTagService.getByAssoci(shopsId),
                    List.class)
            );
        }

        return RestResponse.success().put("data", page);
    }

    /**
     * 店铺列表
     */
    @IgnoreAuth
    @GetMapping("/shopsList")
    @ApiOperation(value = "店铺列表", notes = "店铺列表")
    @ApiImplicitParam(paramType = "query", name = "type", value = "类型，1为普通店铺，2为支行", example = "1", required = true, dataType = "string")
    public RestResponse shopsList(@RequestParam(defaultValue = "1") Integer type) {
        List<MallShopsEntity> shopsEntityList = shopsService.list(
                new QueryWrapper<MallShopsEntity>().eq("TYPE", type).eq("LEVEL", Constant.ONE)
                        .eq("IS_ON_SALE", Constant.ONE).orderByDesc("SORT"));
        return RestResponse.success().put("data", shopsEntityList);
    }

    /**
     * 店铺详情
     */
    @IgnoreAuth
    @GetMapping("/detailBySn")
    @ApiOperation(value = "店铺详情", notes = "店铺详情")
    @ApiImplicitParam(paramType = "query", name = "shopsSn", value = "店铺SN", example = "1", required = true, dataType = "string")
    public RestResponse detailBySn(String shopsSn) {
        MallShopsEntity shopsEntity = shopsService.getOne(new QueryWrapper<MallShopsEntity>().eq("SHOPS_SN", shopsSn), false);
        if (null == shopsEntity) {
            return RestResponse.error("店铺暂未开放");
        }
        return RestResponse.success().put("data", shopsEntity);
    }

    /**
     * 根据店铺ID获取店铺商品分类
     */
    @IgnoreAuth
    @GetMapping("/shopsCategory")
    @ApiOperation(value = "店铺商品分类列表", notes = "根据店铺ID获取店铺商品分类")
    @ApiImplicitParam(paramType = "query", name = "shopsId", value = "店铺ID", example = "1", required = true, dataType = "string")
    public RestResponse shopsCategory(String shopsId) {
        List<MallShopsCategoryEntity> shopsCategoryEntityList = shopsCategoryService.list(
                new QueryWrapper<MallShopsCategoryEntity>().eq("SHOPS_ID", shopsId).eq("STATUS", 1)
                        .orderByAsc("SORT"));
        return RestResponse.success().put("data", shopsCategoryEntityList);
    }

    /**
     * 店铺商品分类列表商品
     */
    @IgnoreAuth
    @GetMapping("/shopsCategoryGoods")
    @ApiOperation(value = "店铺商品分类列表商品", notes = "根据店铺商品分类ID获取商品列表")
    @ApiImplicitParam(paramType = "query", name = "shopsCategoryId", value = "店铺商品分类ID", example = "1", required = true, dataType = "string")
    public RestResponse shopsCategoryGoods(String shopsCategoryId) {
        Map<String, Object> params = new HashMap<>(2);
        params.put("shopsCategoryId", shopsCategoryId);
        params.put("isOnSale", 1);
        List<MallShopsGoodsEntity> shopsCategoryEntityList = shopsGoodsService.queryAll(params);
        return RestResponse.success().put("data", shopsCategoryEntityList);
    }


    /**
     * 店铺商品列表商品（小程序）
     */
    @IgnoreAuth
    @GetMapping("/shopsGoodsList")
    @ApiOperation(value = "店铺商品列表", notes = "根据店铺ID获取商品列表")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "shopsId", value = "店铺ID", example = "1", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "categoryId", value = "分类id", example = "1", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "minIntegral", value = "最小积分", example = "1", dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "integral", value = "最大积分", example = "1", required = true, dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "page", value = "当前页数", example = "1", required = true, dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "limit", value = "每页多少条", example = "10", required = true, dataType = "int")
    })
    public RestResponse shopsGoodsList(@RequestParam Map<String, Object> params) {
        params.put("isOnSale", 1);
        Integer minIntegral = NumberUtils.toInt(params.get("minIntegral") == null ? "0" : params.get("minIntegral").toString(), 0);
        params.put("minIntegral", minIntegral);
        if ("1".equals(params.get("shopsId"))) {
            params.put("shopsId", null);
            // 查找商户自主添加的商品，shposid：1是网上商城的id
            params.put("type", 1);
        }
        Page page = shopsGoodsService.queryPage(params);
        return RestResponse.success().put("page", page);
    }

    /**
     * 店铺商品分类列表商品（小程序）
     */
    @IgnoreAuth
    @GetMapping("/shopsGoodsCategory")
    @ApiOperation(value = "店铺商品分类列表商品", notes = "店铺商品分类列表商品")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "shopsId", value = "店铺ID", example = "1", required = true, dataType = "string"),
    })
    public RestResponse shopsGoodsCategory(String shopsId) {
        List<MallShopsGoodsEntity> list = new ArrayList<>();
        Map params = new HashMap(4);
        if ("1".equals(shopsId)) {
            // 查找商户自主添加的商品，shposid：1是网上商城的id
            params.put("type", 1);
        }
        list = shopsGoodsService.selectMallShopsGoodsCategory(params);
        MallShopsGoodsEntity rootCategory = new MallShopsGoodsEntity();
        rootCategory.setCategoryId("");
        rootCategory.setCategoryName("全部");
        list.add(0, rootCategory);

        return RestResponse.success().put("list", JSONArray.toJSON(list));
    }


    /**
     * 店铺详情
     */
    @IgnoreAuth
    @GetMapping("/detailById")
    @ApiOperation(value = "店铺详情", notes = "店铺详情")
    @ApiImplicitParam(paramType = "query", name = "id", value = "店铺ID", example = "defdsae4434lkjf43j", required = true, dataType = "string")
    public RestResponse detailById(String id) {
        MallShopsDto dto = shopsService.getShopByIdForApp(id);
        if (dto == null) {
            return RestResponse.error("店铺暂未开放！");
        }
        return RestResponse.success().put("data", dto);
    }

    /**
     * 查看同一个品牌下所有的店铺信息
     */
    @IgnoreAuth
    @GetMapping("/listByBrandId")
    @ApiOperation(value = "查看品牌下所有的店铺", notes = "店铺详情")
    @ApiImplicitParam(paramType = "query", name = "brandId", value = "品牌id", required = true, dataType = "string")
    public RestResponse listByBrandId(String brandId) {
        List<MallShopsEntity> list = shopsService.queryAllByBrandId(brandId);
        return RestResponse.success().put("data", list);
    }

    /**
     * 适用门店列表
     */
    @GetMapping("getShopListByCardId")
    @ApiOperation(value = "卡卷适用门店列表", notes = "根据卡卷id获取使用门店信息")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "goodsId", name = "goodsId", value = "商品id", example = "10", dataType = "string")
    })
    @IgnoreAuth
    public RestResponse getShopListByCardId(@RequestParam String goodsId) {
        Map<String, Object> params = new HashMap<>(3);
        params.put("goodsId", goodsId);
        List<Map<String, Object>> maps = cardShopsService.queryPageUnionShops(params);
        return RestResponse.success().put("data", maps);
    }

    /**
     * 获取店铺分类id
     */
    @IgnoreAuth
    @GetMapping("/getShopsCategoryList")
    @ApiOperation(value = "获取店铺分类", notes = "获取店铺分类")
    public RestResponse getShopsCategoryList() {
        List<MallShopsCategoryEntity> shopsCategoryEntityList = shopsCategoryService.list(
                new QueryWrapper<MallShopsCategoryEntity>().eq("STATUS", 1)
                        .orderByDesc("SORT"));
        return RestResponse.success().put("data", shopsCategoryEntityList);
    }

}
